﻿'----------------------------------------------------------------------
' Created with SharpDevelop
' Author: Adam Yarnott, Blue Ninja Software
' Copyright (c) Adam Yarnott, Blue Ninja Software.
' Date: 8/22/2007
' Time: 12:48 PM
'----------------------------------------------------------------------

Imports System.Runtime.InteropServices

Imports System.IO

Imports System.Threading

Namespace Interop
	
	''' <summary>
	''' Interop declarations from user32.dll.
	''' </summary>
	Friend Module User32
		
		#Region "Device Notification Enums"
		
		''' <summary>
		''' Defines Flags parameter for RegisterDeviceNotification function.
		''' </summary>
		Public Enum DeviceNotifyEnum As Int32
		    
		    ''' <summary>The hRecipient parameter is a window handle.</summary>
		    WINDOW_HANDLE			= 0
		    
		    ''' <summary>The hRecipient parameter is a service status handle.</summary>
		    SERVICE_HANDLE			= 1
		    
		    ''' <summary>Notifies the recipient of device interface events for all device interface classes. (The dbcc_classguid member is ignored.)
			''' 	<para>This value can be used only if the dbch_devicetype member is DBT_DEVTYP_DEVICEINTERFACE.</para>
			''' 	<para>Windows 2000 and Windows Me/98: This value is not supported.</para>
			''' </summary>
		    ALL_INTERFACE_CLASSES	= 4
		    
		End Enum
		
	    ''' <summary>
	    ''' Defines the dbch_devicetype member for the DEV_BROADCAST_HDR structure.
	    ''' </summary>
	    Public Enum DeviceTypeEnum As Integer
	        
	        ''' <summary>OEM- or IHV-defined device type. This structure is a DEV_BROADCAST_OEM structure.</summary>
	    	OEM					= 0
	        
	        ''' <summary>Logical volume. This structure is a DEV_BROADCAST_VOLUME structure.</summary>
	    	VOLUME				= 2
	        
	        ''' <summary>Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure.</summary>
	    	PORT				= 3
	        
	        ''' <summary>Class of devices. This structure is a DEV_BROADCAST_DEVICEINTERFACE structure.
			''' 	<para>Windows 95: This value is not supported.</para>
			''' </summary>
	    	DEVICEINTERFACE		= 5
	        
	        ''' <summary>File system handle. This structure is a DEV_BROADCAST_HANDLE structure.
			''' 	<para>Windows 95: This value is not supported.</para>
			''' </summary>
	    	HANDLE				= 6
	    	
	    End Enum
		
		#End Region
		
		#Region "File I/O Enums"
		
		<Flags> _
		Public Enum EFileAttributes As UInteger
		   [Readonly] = &H00000001
		   Hidden = &H00000002
		   System = &H00000004
		   Directory = &H00000010
		   Archive = &H00000020
		   Device = &H00000040
		   Normal = &H00000080
		   Temporary = &H00000100
		   SparseFile = &H00000200
		   ReparsePoint = &H00000400
		   Compressed = &H00000800
		   Offline = &H00001000
		   NotContentIndexed= &H00002000
		   Encrypted = &H00004000
		   Write_Through = &H80000000L
		   Overlapped = &H40000000
		   NoBuffering = &H20000000
		   RandomAccess = &H10000000
		   SequentialScan = &H08000000
		   DeleteOnClose = &H04000000
		   BackupSemantics = &H02000000
		   PosixSemantics = &H01000000
		   OpenReparsePoint = &H00200000
		   OpenNoRecall = &H00100000
		   FirstPipeInstance= &H00080000
		End Enum
		
		#End Region
		
		#Region "Device Notification Structures"
		
		''' <summary>
		''' Serves as a standard header for information related to a device event reported through the WM_DEVICECHANGE message.
		''' 	<para>The members of the DEV_BROADCAST_HDR structure are contained in each device management structure. To determine which structure you have received through WM_DEVICECHANGE, treat the structure as a DEV_BROADCAST_HDR structure and check its dbch_devicetype member.</para>
		''' </summary>
	    <StructLayout(LayoutKind.Sequential)> _
	    Public Structure DEV_BROADCAST_HDR
	        
	        ''' <summary>The size of this structure, in bytes.
			''' 	<para>If this is a user-defined event, this member must be the size of this header, plus the size of the variable-length data in the _DEV_BROADCAST_USERDEFINED structure.</para>
			''' </summary>
	        Public dbch_size As Integer
	        
	        ''' <summary>The device type, which determines the event-specific information that follows the first three members.</summary>
	        Public dbch_devicetype As DeviceTypeEnum
	        
	        ''' <summary>Reserved; do not use.</summary>
	        Public dbch_reserved As Integer
	        
	    End Structure
		
	    ''' <summary>
	    ''' Contains information about a class of devices.
	    ''' </summary>
	    <StructLayout(LayoutKind.Sequential, CharSet := CharSet.Unicode)> _
	    Public Structure DEV_BROADCAST_DEVICEINTERFACE
	        
	        ''' <summary>The size of this structure, in bytes. This is the size of the members plus the actual length of the dbcc_name string (the null character is accounted for by the declaration of dbcc_name as a one-character array.)</summary>
	        Public dbcc_size As Integer
	        
	        ''' <summary>Set to DBT_DEVTYP_DEVICEINTERFACE.</summary>
	        Public dbcc_devicetype As DeviceTypeEnum
	        
	        ''' <summary>Reserved; do not use.</summary>
	        Public dbcc_reserved As Integer
	        
	        ''' <summary>The GUID for the interface device class.</summary>
	        Public dbcc_classguid As Guid
	        
	        ''' <summary>A null-terminated string that specifies the name of the device.
			''' 	<para>When this structure is returned to a window through the WM_DEVICECHANGE message, the dbcc_name string is converted to ANSI as appropriate. Services always receive a Unicode string, whether they call RegisterDeviceNotificationW or RegisterDeviceNotificationA.</para>
			''' </summary>
	        <MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _
	        Public dbcc_name As String
	        
	    End Structure
	
		''' <summary>
		''' Contains information about a file system handle.
		''' </summary>
		''' <remarks>Note: Members applicable only to DBT_CUSTOMEVENT have been omitted.</remarks>
	    <StructLayout(LayoutKind.Sequential)> _
	    Public Structure DEV_BROADCAST_HANDLE
	        
	        ''' <summary>The size of this structure, in bytes.</summary>
	        Public dbch_size As Integer
	        
	        ''' <summary>Set to DBT_DEVTYP_HANDLE.</summary>
	        Public dbch_devicetype As DeviceTypeEnum
	        
	        ''' <summary>Reserved; do not use.</summary>
	        Public dbch_reserved As Integer
	        
	        ''' <summary>A handle to the device to be checked.</summary>
	        Public dbch_handle As Integer
	        
	        ''' <summary>A handle to the device notification. This handle is returned by RegisterDeviceNotification.</summary>
	        Public dbch_hdevnotify As Integer
	        
	    End Structure
		
		#End Region
		
		#Region "Device Notification Imports"
		
		''' <summary>
		''' Registers the device or type of device for which a window will receive notifications.
		''' </summary>
		''' <param name="hRecipient">[in] A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification.
		''' 	<para>Services can specify either a window handle or service status handle.</para>
		''' </param>
		''' <param name="NotificationFilter">[in] A pointer to a block of data that specifies the type of device for which notifications should be sent. This block always begins with the DEV_BROADCAST_HDR structure. The data following this header is dependent on the value of the dbch_devicetype member, which can be DBT_DEVTYP_DEVICEINTERFACE or DBT_DEVTYP_HANDLE. For more information, see Remarks.</param>
		''' <param name="Flags"></param>
		''' <returns>If the function succeeds, the return value is a device notification handle.
		''' 	<para>If the function fails, the return value is NULL. To get extended error information, call GetLastError.</para>
		''' </returns>
		''' <remarks>Applications send event notifications using the BroadcastSystemMessage function. Any application with a top-level window can receive basic notifications by processing the WM_DEVICECHANGE message. Applications can use the RegisterDeviceNotification function to register to receive device notifications.
		''' 	<para>Services can use the RegisterDeviceNotification function to register to receive device notifications. If a service specifies a window handle in the hRecipient parameter, the notifications are sent to the window procedure. If hRecipient is a service status handle, SERVICE_CONTROL_DEVICEEVENT notifications are sent to the service control handler. For more information about the service control handler, see HandlerEx.</para>
		''' 	<para>Be sure to handle Plug and Play device events as quickly as possible. Otherwise, the system may become unresponsive. If your event handler is to perform an operation that may block execution (such as I/O), it is best to start another thread to perform the operation asynchronously.</para>
		''' 	<para>Device notification handles returned by RegisterDeviceNotification must be closed by calling the UnregisterDeviceNotification function when they are no longer needed.</para>
		''' 	<para>The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast to all top-level windows for port devices. Therefore, it is not necessary to call RegisterDeviceNotification for ports, and the function fails if the dbch_devicetype member is DBT_DEVTYP_PORT. Volume notifications are also broadcast to top-level windows, so the function fails if dbch_devicetype is DBT_DEVTYP_VOLUME. OEM-defined devices are not used directly by the system, so the function fails if dbch_devicetype is DBT_DEVTYP_OEM.</para>
		''' </remarks>
	    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
	    Function RegisterDeviceNotification(ByVal hRecipient As IntPtr, ByVal NotificationFilter As IntPtr, ByVal Flags As DeviceNotifyEnum) As IntPtr
	    End Function
	    
	    ''' <summary>
	    ''' Closes the specified device notification handle.
	    ''' </summary>
	    ''' <param name="Handle">[in] Device notification handle returned by the RegisterDeviceNotification function.</param>
	    ''' <returns>If the function succeeds, the return value is nonzero.
		''' 	<para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
		''' </returns>
	    ''' <remarks>Windows Me/98: Do not call UnregisterDeviceNotification from within the message handler for the WM_DEVICECHANGE message. Doing so can make these versions of Windows unstable.</remarks>
	    <DllImport("user32.dll")> _
	    Function UnregisterDeviceNotification(ByVal Handle As IntPtr) As Boolean
	    End Function
		
		#End Region
		
		#Region "File I/O Imports"
		
		<DllImport("Kernel32.dll", SetLastError := True, CharSet := CharSet.Auto)> _
		Public Function CreateFile(ByVal fileName As String, ByVal fileAccess As FileAccess, ByVal fileShare As FileShare, ByVal securityAttributes As IntPtr, ByVal creationDisposition As FileMode, ByVal flags As EFileAttributes, ByVal template As IntPtr) As IntPtr
		'Public Function CreateFile(ByVal fileName As String, <MarshalAs(UnmanagedType.U4)> ByVal fileAccess As FileAccess, <MarshalAs(UnmanagedType.U4)> ByVal fileShare As FileShare, ByVal securityAttributes As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal creationDisposition As FileMode, <MarshalAs(UnmanagedType.U4)> ByVal flags As EFileAttributes, ByVal template As IntPtr) As IntPtr	' Microsoft.Win32.SafeHandles.SafeFileHandle
		End Function
		
		'TODO: Replace CreateEvent with System.Threading.AutoResetEvent, ManualResetEvent
	
		'TODO: Replace CreateFile with System.IO.File, FileInfo
	
		'TODO: Replace WaitForSingleObject with System.Threading.WaitHandle.WaitOne
	
		#End Region
		
	End Module
	
End Namespace
